home *** CD-ROM | disk | FTP | other *** search
- #include "misc.hpp"
- #include "brdsize.hpp"
- #include "chess.hpp"
- #include "chessui.hpp"
- #include "chcharui.hpp"
-
- CHESSUSERIFACE ChessUI;
-
- const char whiteText[] = "White",
- blackText[] = "Black";
-
- LOCAL const char *colorText(PIECECOLOR color)
- { return(color == WHITE ? whiteText : blackText); }
-
- // returns piece abbreviation to be displayed in board squares
- // for a given piece
- LOCAL const char *pieceAbbrev
- (
- PIECECOLOR color,
- PIECETYPE type
- )
- {
- if (color == WHITE)
- switch (type)
- {
- case TYPEKING: return("WK");
- case TYPEQUEEN: return("WQ");
- case TYPEBISHOP: return("WB");
- case TYPEKNIGHT: return("WN");
- case TYPEROOK: return("WR");
- case TYPEPAWN: return("WP");
- }
- else
- switch (type)
- {
- case TYPEKING: return("BK");
- case TYPEQUEEN: return("BQ");
- case TYPEBISHOP: return("BB");
- case TYPEKNIGHT: return("BN");
- case TYPEROOK: return("BR");
- case TYPEPAWN: return("BP");
- }
- return(""); // dummy return
- }
-
- const char kingText[] = " King",
- queenText[] = " Queen",
- bishopText[] = " Bishop",
- knightText[] = " Knight",
- rookText[] = " Rook",
- pawnText[] = " Pawn";
-
- // fills in two entries in a message textList with color/name of
- // a piece
- LOCAL void pieceText
- (
- PIECECOLOR color,
- PIECETYPE type,
- const char **textList
- )
- {
- *(textList++) = colorText(color);
-
- switch (type)
- {
- case TYPEKING:
- *textList = kingText;
- return;
-
- case TYPEQUEEN:
- *textList = queenText;
- return;
-
- case TYPEBISHOP:
- *textList = bishopText;
- return;
-
- case TYPEKNIGHT:
- *textList = knightText;
- return;
-
- case TYPEROOK:
- *textList = rookText;
- return;
-
- case TYPEPAWN:
- *textList = pawnText;
- return;
- }
- }
-
- // base textLists for messages. terminated by null pointers. some
- // have null pointer place holders for variable portions of message.
-
- const char *noMemory[] =
- {
- "Insufficient memory. Press any key to exit:",
- (char *) 0
- };
-
- const char *checkMated[] =
- {
- (char *) 0,
- " King in checkmate. Press any key to exit:",
- (char *) 0
- };
- const int MATEDCOLORINDEX = 0;
-
- const char *staleMate[] =
- {
- (char *) 0,
- " King in stalemate. Press any key to exit:",
- (char *) 0
- };
- const int STALEMATEDCOLORINDEX = 0;
-
- const char *selectPiece[] =
- {
- (char *) 0,
- " Player: Select piece to move with arrow keys, then hit enter:",
- (char *) 0
- };
- const int SELECTCOLORINDEX = 0;
-
- const char *illegalSelection[] =
- {
- "That location does not contain one of your pieces."
- " Press any key to try again:",
- (char *) 0
- };
-
- const char *moveIllegal[] =
- {
- "You cannot move the selected piece to that location."
- " Press any key to try again:",
- (char *) 0
- };
-
- const char *wouldLoseKing[] =
- {
- "This move would result in your King being taken by the ",
- (char *) 0,
- (char *) 0,
- ". Press any key to select another move:",
- (char *) 0
- };
- const int DANGERINDEX = 1;
-
- const char *castleQueenRook[] =
- {
- "Do you want to castle with Queen's Rook? (Type Y or N):",
- (char *) 0
- };
-
- const char *castleKingRook[] =
- {
- "Do you want to castle with King's Rook? (Type Y or N):",
- (char *) 0
- };
-
- const char *selectDest[] =
- {
- "Select destination of move with arrow keys, then hit enter:",
- (char *) 0
- };
-
- const char *promoteToWhat[] =
- {
- "Do you want your Pawn to be promoted to a Queen, Bishop, "
- "Knight or Rook? (Type Q, B, K or R):",
- (char *) 0
- };
-
- // character key lists
-
- const char promoteOptions[] = "qQbBkKrR";
- const PIECETYPE promoteType[] = { TYPEQUEEN, TYPEBISHOP, TYPEKNIGHT,
- TYPEROOK };
-
- const char yesNoAnswer[] = "yYnN";
- const int YESINDEX = 0;
- const int NOINDEX = 1;
-
- // more message text lists
-
- const char *thinking[] =
- {
- (char *) 0,
- " Player thinking, please wait...",
- (char *) 0
- };
- const int THINKINGCOLORINDEX = 0;
-
- const char *doCastleQueenRook[] =
- {
- (char *) 0,
- " Player castles with Queen's Rook. Press any key to continue:",
- (char *) 0
- };
- const char *doCastleKingRook[] =
- {
- (char *) 0,
- " Player castles with King's Rook. Press any key to continue:",
- (char *) 0
- };
- const int CASTLECOLORINDEX = 0;
-
- const char *whatMoved[] =
- {
- (char *) 0,
- " Player moves ",
- (char *) 0,
- (char *) 0,
- ". Press any key to continue:",
- (char *) 0
- };
- const int MOVECOLORINDEX = 0;
- const int MOVEPIECEINDEX = 2;
-
- const char *whatMovedCaptured[] =
- {
- (char *) 0,
- " Player moves ",
- (char *) 0,
- (char *) 0,
- ", capturing ",
- (char *) 0,
- (char *) 0,
- ". Press any key to continue:",
- (char *) 0
- };
- const int CAPTURINGCOLORINDEX = 0;
- const int CAPTURINGPIECEINDEX = 2;
- const int CAPTUREDPIECEINDEX = 5;
-
- const char *doPromotion[] =
- {
- (char *) 0,
- " Player promotes Pawn to ",
- (char *) 0,
- (char *) 0,
- ". Press any key to continue:",
- (char *) 0
- };
- const int PROMOTECOLORINDEX = 0;
- const int PROMOTEPIECEINDEX = 2;
-
- void CHESSUSERIFACE::outOfMemory(void)
- {
- ChessCharUI.showMessage(noMemory, (char *) 0, (uint *) 0);
-
- return;
- }
-
- void CHESSUSERIFACE::init(const BOARD &board)
- {
- int row, col;
- PIECE *p;
-
- ChessCharUI.initScreen();
-
- for (row = 0; row < NUMROWS; row++)
- for (col = 0; col < NUMCOLS; col++)
- {
- p = board.whatPiece(row, col);
- if (p)
- ChessCharUI.showPiece
- (
- POSITION(row, col),
- pieceAbbrev(p->whatColor(), p->whatType())
- );
- }
-
- return;
- }
-
- void CHESSUSERIFACE::mated(PIECECOLOR color)
- {
- checkMated[MATEDCOLORINDEX] = colorText(color);
- ChessCharUI.showMessage(checkMated, (char *) 0, (uint *) 0);
-
- return;
- }
-
- void CHESSUSERIFACE::staleMated(PIECECOLOR color)
- {
- staleMate[STALEMATEDCOLORINDEX] = colorText(color);
- ChessCharUI.showMessage(staleMate, (char *) 0, (uint *) 0);
-
- return;
- }
-
- BOOL CHESSUSERIFACE::userMove(BOARD &board, PIECECOLOR color)
- {
- POSITION start, end;
- PIECE *p;
- uint keyIndex;
- MOVESTATUS moveStatus;
- MOVEUNDODATA dummy;
-
- selectPiece[SELECTCOLORINDEX] = colorText(color);
-
- // loop to get legal move
- for ( ; ; )
- {
- // loop to get piece to move
- for ( ; ; )
- {
- start.row = start.col = 0;
- if (!ChessCharUI.selectPosition(selectPiece, start))
- return(FALSE);
-
- p = board.whatPiece(start);
- if (p)
- if (p->whatColor() == color)
- break;
-
- if (!ChessCharUI.showMessage(illegalSelection,
- (char *) 0, (uint *) 0))
- return(FALSE);
-
- ChessCharUI.clearSelect(start);
- }
-
- if (board.userCanCastle(QUEENSIDECASTLE, color))
- if ((p->whatType() == TYPEKING) ||
- ((p->whatType() == TYPEROOK) && (start.row == 0)))
- {
- if (!ChessCharUI.showMessage(castleQueenRook,
- yesNoAnswer, &keyIndex))
- return(FALSE);
- if ((keyIndex / 2) == YESINDEX)
- {
- ChessCharUI.clearSelect(start);
- board.castle(QUEENSIDECASTLE, color, dummy);
- ChessCharUI.clearPiece(POSITION(0, start.col));
- ChessCharUI.showPiece
- (
- POSITION(3, start.col),
- pieceAbbrev(color, TYPEROOK)
- );
- ChessCharUI.clearPiece(POSITION(4, start.col));
- ChessCharUI.showPiece
- (
- POSITION(2, start.col),
- pieceAbbrev(color, TYPEKING)
- );
- return(TRUE);
- }
- }
-
- if (board.userCanCastle(KINGSIDECASTLE, color))
- if ((p->whatType() == TYPEKING) ||
- ((p->whatType() == TYPEROOK) && (start.row == 7)))
- {
- if (!ChessCharUI.showMessage(castleKingRook,
- yesNoAnswer, &keyIndex))
- return(FALSE);
- if ((keyIndex / 2) == YESINDEX)
- {
- ChessCharUI.clearSelect(start);
- board.castle(KINGSIDECASTLE, color, dummy);
- ChessCharUI.clearPiece(POSITION(7, start.col));
- ChessCharUI.showPiece
- (
- POSITION(5, start.col),
- pieceAbbrev(color, TYPEROOK)
- );
- ChessCharUI.clearPiece(POSITION(4, start.col));
- ChessCharUI.showPiece
- (
- POSITION(6, start.col),
- pieceAbbrev(color, TYPEKING)
- );
- return(TRUE);
- }
- }
-
- end = start;
- if (!ChessCharUI.selectPosition(selectDest, end))
- return(FALSE);
-
- moveStatus = board.doUserMove
- (
- start,
- end
- );
-
- if ((moveStatus.status == MOVEDONE) ||
- (moveStatus.status == MOVEENPASSANT))
- break;
-
- if (moveStatus.status == ILLEGALMOVE)
- {
- if (!ChessCharUI.showMessage(moveIllegal, (char *) 0,
- (uint *) 0))
- return(FALSE);
- }
- else // king would be taken
- {
- pieceText
- (
- OtherColor(color),
- board.whatPiece(moveStatus.dangerToKing)->whatType(),
- wouldLoseKing + DANGERINDEX
- );
- if (!ChessCharUI.showMessage(wouldLoseKing, (char *) 0,
- (uint *) 0))
- return(FALSE);
- }
- ChessCharUI.clearSelect(start);
- ChessCharUI.clearSelect(end);
-
- } // end loop to get legal move
-
- ChessCharUI.clearSelect(start);
- ChessCharUI.clearPiece(start);
- ChessCharUI.clearPiece(end);
- if (moveStatus.status == MOVEENPASSANT)
- ChessCharUI.clearPiece(POSITION(end.row, start.col));
- ChessCharUI.showPiece
- (
- end,
- pieceAbbrev(color, p->whatType())
- );
-
- if (board.canPromote(end))
- {
- if (!ChessCharUI.showMessage(promoteToWhat, promoteOptions,
- &keyIndex))
- return(FALSE);
- keyIndex /= 2;
- board.promote(end, promoteType[keyIndex]);
- ChessCharUI.clearPiece(end);
- ChessCharUI.showPiece
- (
- end,
- pieceAbbrev(color, promoteType[keyIndex])
- );
- }
- ChessCharUI.clearSelect(end);
-
- return(TRUE);
- }
-
- void CHESSUSERIFACE::thinkingMessage(PIECECOLOR color)
- {
- thinking[THINKINGCOLORINDEX] = colorText(color);
-
- ChessCharUI.showMessage(thinking);
-
- return;
- }
-
- void CHESSUSERIFACE::clearMessage(void)
- {
- ChessCharUI.clearMessage();
-
- return;
- }
-
- BOOL CHESSUSERIFACE::computerMove
- (
- BOARD &board,
- PIECECOLOR color,
- PIECEMOVE &moveInfo
- )
- {
- int backCol = color == WHITE ? 0 : 7;
- MOVEUNDODATA undoData;
-
- switch (moveInfo.type)
- {
- case KINGSIDECASTLE:
- board.castle(KINGSIDECASTLE, color, undoData);
- ChessCharUI.clearPiece(POSITION(7, backCol));
- ChessCharUI.clearPiece(POSITION(4, backCol));
- ChessCharUI.showPiece
- (
- POSITION(5, backCol),
- pieceAbbrev(color, TYPEROOK)
- );
- ChessCharUI.showPiece
- (
- POSITION(6, backCol),
- pieceAbbrev(color, TYPEKING)
- );
- ChessCharUI.setSelect(POSITION(5, backCol));
- ChessCharUI.setSelect(POSITION(6, backCol));
- doCastleKingRook[CASTLECOLORINDEX] = colorText(color);
- if (!ChessCharUI.showMessage(doCastleKingRook,
- (char *) 0, (uint *) 0))
- return(FALSE);
- ChessCharUI.clearSelect(POSITION(5, backCol));
- ChessCharUI.clearSelect(POSITION(6, backCol));
- return(TRUE);
-
- case QUEENSIDECASTLE:
- board.castle(QUEENSIDECASTLE, color, undoData);
- ChessCharUI.clearPiece(POSITION(0, backCol));
- ChessCharUI.clearPiece(POSITION(4, backCol));
- ChessCharUI.showPiece
- (
- POSITION(3, backCol),
- pieceAbbrev(color, TYPEROOK)
- );
- ChessCharUI.showPiece
- (
- POSITION(2, backCol),
- pieceAbbrev(color, TYPEKING)
- );
- ChessCharUI.setSelect(POSITION(3, backCol));
- ChessCharUI.setSelect(POSITION(2, backCol));
- doCastleQueenRook[CASTLECOLORINDEX] = colorText(color);
- if (!ChessCharUI.showMessage(doCastleQueenRook,
- (char *) 0, (uint *) 0))
- return(FALSE);
- ChessCharUI.clearSelect(POSITION(3, backCol));
- ChessCharUI.clearSelect(POSITION(2, backCol));
- return(TRUE);
-
- case NORMALMOVE:
- board.doMove(moveInfo.start, moveInfo.end, undoData);
- ChessCharUI.clearPiece(moveInfo.start);
- ChessCharUI.clearPiece(moveInfo.end);
- if (undoData.enPassantEffect == ENPASSANTCAPTURE)
- ChessCharUI.clearPiece(POSITION(moveInfo.end.row,
- moveInfo.start.col));
- ChessCharUI.showPiece
- (
- moveInfo.end,
- pieceAbbrev(color,
- board.whatPiece(moveInfo.end)->whatType())
- );
- ChessCharUI.setSelect(moveInfo.start);
- ChessCharUI.setSelect(moveInfo.end);
-
- if (undoData.capturedPiece)
- {
- whatMovedCaptured[CAPTURINGCOLORINDEX] = colorText(color);
- pieceText
- (
- color,
- board.whatPiece(moveInfo.end)->whatType(),
- whatMovedCaptured + CAPTURINGPIECEINDEX
- );
- pieceText
- (
- OtherColor(color),
- undoData.capturedPiece->whatType(),
- whatMovedCaptured + CAPTUREDPIECEINDEX
- );
-
- delete undoData.capturedPiece;
-
- if (!ChessCharUI.showMessage(whatMovedCaptured,
- (char *) 0, (uint *) 0))
- return(FALSE);
- }
- else
- {
- whatMoved[MOVECOLORINDEX] = colorText(color);
- pieceText
- (
- color,
- board.whatPiece(moveInfo.end)->whatType(),
- whatMoved + MOVEPIECEINDEX
- );
- if (!ChessCharUI.showMessage(whatMoved,
- (char *) 0, (uint *) 0))
- return(FALSE);
- }
-
- if (moveInfo.promoteType != TYPENOPIECE)
- {
- board.promote(moveInfo.end, moveInfo.promoteType);
- ChessCharUI.clearPiece(moveInfo.end);
- ChessCharUI.showPiece
- (
- moveInfo.end,
- pieceAbbrev(color, moveInfo.promoteType)
- );
- doPromotion[PROMOTECOLORINDEX] = colorText(color);
- pieceText
- (
- color,
- moveInfo.promoteType,
- doPromotion + PROMOTEPIECEINDEX
- );
- if (!ChessCharUI.showMessage(doPromotion, (char *) 0,
- (uint *) 0))
- return(FALSE);
- }
- ChessCharUI.clearSelect(moveInfo.start);
- ChessCharUI.clearSelect(moveInfo.end);
-
- return(TRUE);
-
- } // end of switch
-
- return(FALSE);
-
- } // end of function
-